//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.jeeplus.config;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.jeeplus.core.errors.ErrorConstants;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.authentication.*;
import org.jasig.cas.client.configuration.ConfigurationKey;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class AuthenticationFilterNew extends AbstractCasFilter {




    private String casServerLoginUrl;
    private boolean renew;
    private boolean gateway;
    private GatewayResolver gatewayStorage;
    private AuthenticationRedirectStrategy authenticationRedirectStrategy;
    private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass;
    private static final Map<String, Class<? extends UrlPatternMatcherStrategy>> PATTERN_MATCHER_TYPES = new HashMap();

    public AuthenticationFilterNew() {
        this(Protocol.CAS2);
    }

    protected AuthenticationFilterNew(Protocol protocol) {
        super(protocol);
        this.renew = false;
        this.gateway = false;
        this.gatewayStorage = new DefaultGatewayResolverImpl();
        this.authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();
        this.ignoreUrlPatternMatcherStrategyClass = null;
    }

    protected void initInternal(FilterConfig filterConfig) throws ServletException {
        if (!this.isIgnoreInitConfiguration()) {
            super.initInternal(filterConfig);
            String loginUrl = this.getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL);
            if (loginUrl != null) {
                this.setCasServerLoginUrl(loginUrl);
            } else {
                this.setCasServerUrlPrefix(this.getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX));
            }

            this.setRenew(this.getBoolean(ConfigurationKeys.RENEW));
            this.setGateway(this.getBoolean(ConfigurationKeys.GATEWAY));
            String ignorePattern = this.getString(ConfigurationKeys.IGNORE_PATTERN);
            String ignoreUrlPatternType = this.getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE);
            Class gatewayStorageClass;
            if (ignorePattern != null) {
                gatewayStorageClass = (Class) PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);
                if (gatewayStorageClass != null) {
                    this.ignoreUrlPatternMatcherStrategyClass = (UrlPatternMatcherStrategy) ReflectUtils.newInstance(gatewayStorageClass.getName(), new Object[0]);
                } else {
                    try {
                        this.logger.trace("Assuming {} is a qualified class name...", ignoreUrlPatternType);
                        this.ignoreUrlPatternMatcherStrategyClass = (UrlPatternMatcherStrategy) ReflectUtils.newInstance(ignoreUrlPatternType, new Object[0]);
                    } catch (IllegalArgumentException var7) {
                        this.logger.error("Could not instantiate class [{}]", ignoreUrlPatternType, var7);
                    }
                }

                if (this.ignoreUrlPatternMatcherStrategyClass != null) {
                    this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);
                }
            }

            gatewayStorageClass = this.getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS);
            if (gatewayStorageClass != null) {
                this.setGatewayStorage((GatewayResolver) ReflectUtils.newInstance(gatewayStorageClass, new Object[0]));
            }

            Class<? extends AuthenticationRedirectStrategy> authenticationRedirectStrategyClass = this.getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS);
            if (authenticationRedirectStrategyClass != null) {
                this.authenticationRedirectStrategy = (AuthenticationRedirectStrategy) ReflectUtils.newInstance(authenticationRedirectStrategyClass, new Object[0]);
            }
        }

    }

    public void init() {
        super.init();
        String message = String.format("one of %s and %s must not be null.", ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName());
        CommonUtils.assertNotNull(this.casServerLoginUrl, message);
    }

    public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 放行静态资源
        String servletPath = request.getServletPath();
        //String s = request.getRequestURL().toString();
        //System.out.println("访问路径" + servletPath);
        ConfigurationKey<String> clientUrl = new ConfigurationKey("clientUrl", (Object)null);
        String clientPath = this.getString(clientUrl);
        //System.out.println("配置的地址" + this.getString(clientUrl));
        String modifiedServiceUrl = this.getString(ConfigurationKeys.SERVER_NAME);
        if (clientPath.equals(servletPath)) {

            String ticket = this.retrieveTicketFromRequest(request);
            if (!CommonUtils.isNotBlank(ticket)) {
                System.out.println("ticket:"+ticket);
                this.logger.debug("no ticket and no assertion found");
                this.logger.debug("Constructed service url: {}", modifiedServiceUrl);
                //String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, this.getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
                String urlToRedirectTo = this.casServerLoginUrl+"?service="+modifiedServiceUrl;
                this.logger.debug("redirecting to \"{}\"", urlToRedirectTo);
                this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
                return;
            }

        }
        filterChain.doFilter(request, response);
    }

//    public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        HttpServletRequest request = (HttpServletRequest) servletRequest;
//        HttpServletResponse response = (HttpServletResponse) servletResponse;
//        // 放行静态资源
//        if (isStaticResource(request)) {
//            filterChain.doFilter(request, response);
//            return;
//        }
//        if (this.isRequestUrlExcluded(request)) {
//            this.logger.debug("Request is ignored.");
//            filterChain.doFilter(request, response);
//        } else {
//            // 添加请求日志，便于调试
//            String requestId = UUID.randomUUID().toString();
//            HttpSession session = request.getSession(false);
//            // 打印Session信息
//            //HttpSession session = request.getSession(false);
//            if (session != null) {
//                this.logger.debug("Session {} exists, ID: {}", requestId, session.getId());
//                this.logger.debug("Session attributes: {}", Collections.list(session.getAttributeNames()));
//            } else {
//                this.logger.debug("Session {} is null", requestId);
//            }
//
//            // 打印Cookie信息
//            Cookie[] cookies = request.getCookies();
//            if (cookies != null) {
//                for (Cookie cookie : cookies) {
//                    if ("JSESSIONID".equals(cookie.getName())) {
//                        this.logger.debug("JSESSIONID cookie: {}", cookie.getValue());
//                    }
//                }
//            }
//            Assertion assertion = session != null ? (Assertion) session.getAttribute("_const_cas_assertion_") : null;
//            if (assertion != null) {
//                filterChain.doFilter(request, response);
//            } else {
//                String serviceUrl = this.constructServiceUrl(request, response);
//                String ticket = this.retrieveTicketFromRequest(request);
//                boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
//                if (!CommonUtils.isNotBlank(ticket) && !wasGatewayed) {
//                    if (isAjaxRequest(request)) {
//                        String errMsg = ErrorConstants.LOGIN_ERROR_NOT_LOGIN_IN;
//                        response.setStatus(HttpStatus.UNAUTHORIZED.value());
//                        response.setCharacterEncoding("UTF-8");
//                        response.setContentType("application/json; charset=utf-8");
//                        PrintWriter printWriter = response.getWriter();
//                        printWriter.write(errMsg);
//                        printWriter.flush();
//                    } else {
//                        this.logger.debug("no ticket and no assertion found");
//                        String modifiedServiceUrl;
//                        if (this.gateway) {
//                            this.logger.debug("setting gateway attribute in session");
//                            modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
//                        } else {
//                            modifiedServiceUrl = serviceUrl;
//                        }
//
//                        this.logger.debug("Constructed service url: {}", modifiedServiceUrl);
//                        String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, this.getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
//                        this.logger.debug("redirecting to \"{}\"", urlToRedirectTo);
////                    String errMsg = ErrorConstants.LOGIN_ERROR_NOT_LOGIN_IN;
////                    response.setStatus ( HttpStatus.UNAUTHORIZED.value ( ) );
////                    response.setCharacterEncoding ( "UTF-8" );
////                    response.setContentType ( "application/json; charset=utf-8" );
////                    PrintWriter printWriter = response.getWriter ( );
////                    printWriter.write ( errMsg );
////                    printWriter.flush ( );
//                        this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
//
//                    }
//                    filterChain.doFilter(request, response);
//
//                } else {
//                    filterChain.doFilter(request, response);
//                }
//            }
//        }
//    }

    private boolean isAjaxRequest(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) ||
                "application/json".equals(request.getHeader("Content-Type")) ||
                request.getHeader("Accept") != null && request.getHeader("Accept").contains("application/json");
    }

    public final void setRenew(boolean renew) {
        this.renew = renew;
    }

    public final void setGateway(boolean gateway) {
        this.gateway = gateway;
    }

    public final void setCasServerUrlPrefix(String casServerUrlPrefix) {
        this.setCasServerLoginUrl(CommonUtils.addTrailingSlash(casServerUrlPrefix) + "login");
    }

    public final void setCasServerLoginUrl(String casServerLoginUrl) {
        this.casServerLoginUrl = casServerLoginUrl;
    }

    public final void setGatewayStorage(GatewayResolver gatewayStorage) {
        this.gatewayStorage = gatewayStorage;
    }

    private boolean isRequestUrlExcluded(HttpServletRequest request) {
        if (this.ignoreUrlPatternMatcherStrategyClass == null) {
            return false;
        } else {
            StringBuffer urlBuffer = request.getRequestURL();
            if (request.getQueryString() != null) {
                urlBuffer.append("?").append(request.getQueryString());
            }

            String requestUri = urlBuffer.toString();
            return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);
        }
    }

    public final void setIgnoreUrlPatternMatcherStrategyClass(UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass) {
        this.ignoreUrlPatternMatcherStrategyClass = ignoreUrlPatternMatcherStrategyClass;
    }

    static {
        PATTERN_MATCHER_TYPES.put("CONTAINS", ContainsPatternUrlPatternMatcherStrategy.class);
        PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class);
        PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class);
    }


    /**
     * 判断是否为静态资源请求
     */
    private boolean isStaticResource(HttpServletRequest request) {
        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();

        // 移除上下文路径
        if (contextPath != null && uri.startsWith(contextPath)) {
            uri = uri.substring(contextPath.length());
        }

        // 常见的静态资源路径和文件扩展名
        String[] staticPaths = {"/static/", "/public/", "/resources/", "/webjars/", "/css/", "/js/", "/images/", "/fonts/", "/assets/"};
        String[] staticExtensions = {".css", ".js", ".jpg", ".jpeg", ".png", ".gif", ".ico", ".svg", ".woff", ".woff2", ".ttf", ".eot", ".map"};

        // 检查静态资源路径
        for (String path : staticPaths) {
            if (uri.startsWith(path)) {
                return true;
            }
        }

        // 检查静态文件扩展名
        for (String ext : staticExtensions) {
            if (uri.toLowerCase().endsWith(ext)) {
                return true;
            }
        }

        // 放行常见的静态资源请求
        if (uri.equals("/") || uri.equals("/favicon.ico")) {
            return true;
        }

        return false;
    }
}
